package com.echo.boot.design.turing.singleton.lazysingleton;

/**
 * Created with IntelliJ IDEA
 * Created By CQ
 * Date: 2020/7/25
 * Time: 22:32
 *
 * @author Administrator
 */
public class LazySingleton {
    public static void main(String[] args) throws Exception {
        // 单线程的情况下
//        LazySingleton instance = LazySingleton.getInstance();
//        LazySingleton instance1 = LazySingleton.getInstance();
//        System.out.println(instance == instance1);
        // 多线程的情况下 所以在多线程的情况下做出双重校验 Double check
        new Thread(() -> {
            LazySingleton instance = LazySingleton.getInstance();
            System.out.println(instance.hashCode());
        }).start();
        new Thread(() -> {
            LazySingleton instance = LazySingleton.getInstance();
            System.out.println(instance.hashCode());
        }).start();


    }

    private static LazySingleton instance;

    private LazySingleton() {
    }

    public static LazySingleton getInstance() {
        // 出现的问题
        // 1.t1,t2 同时走过 下一行代码,其中一个线程拿到锁,另外一个等待
        // 2.t1 判断 instance 不为空,但是 t2 线程还没初始化（指令重排序）
        if (instance == null) {
            synchronized (LazySingleton.class) {
                // 再次判断实例是否初始化;
                // 如果存在,其中一个线程直接返回实例
                if (instance == null) {
                    // 此处会出现指令从排序的情况,
                    //1.分配空间 2.初始化 3.引用赋值
                    // 第二,三步 顺序会从排序,从而引起 还没赋值就返回了
                    instance = new LazySingleton();
                }
            }
        }
        return instance;
    }

}
